﻿(function ( window ) {
	
	// Refactor needs;
	
	var window = window;
	var document = window.document;
	
	Object.prototype.save = function ( ls_key )
	{
		return localStorage[ls_key] = JSON.stringify (this);
	}
	Object.prototype.load = function ( ls_key )
	{
		var _loaded = JSON.parse(localStorage[ls_key]);
		for (var i in _loaded)
		{
			if (i != 'load' && i != 'save')
			{
				this[i] = _loaded[i];
			}
		}
		return _loaded;
	}
	
	try {
		var activePlugins = Object.load('plugins');
		console.log ( '0' );
	} catch ( e ) {
		window.localStorage['plugins'] = '[]';
		var activePlugins = new Object ();
		console.log ( '1' );
	}
	
	
	var Plugin = function ( p )
	{
		/*	p — is the parameters object
			{
				name:	'plugin_name',
				filter:	/filter regex/,
				action:	function ()
				{
					…
				},
				classes: {
							"plugin_class_name": finction () {…},
							…
						}
			}
		*/
		
		this.name = p.name ? p.name : '';
		this.filter = p.filter ? p.filter : /.*/;
		this.action = p.action ? p.action : function () {};	
		this.classes = p.classes ? p.classes : {};
	}
	
	var PluginDispatcher = function ( l )
	{
			/*	l — is the list of plugins array
				[
					new Plugin ({
						name:	'plugin_name',
						filter:	new Regexp ('.*'),
						action:	function ()
						{
							…
						},
						classes: {
							"plugin_class_name": finction () {…},
							…
						}
					}),
					new Plugin ( { … } ),
				]
			*/
			
			var path =  window.location.pathname;
			var _plugins = l ? l : [];
			
			for (i in _plugins)
			{
				if ( ( activePlugins[_plugins[i].name] && _plugins[i].filter.test(path)) && (_plugins[i] instanceof Plugin) )
				{
					_plugins[i].action.call (_plugins[i]);
				}
			}
	}
	
	// QMenu (fixed-side) class;
	var QMenu = function ( l )
	{
		/*	l - list of QButton objects
			[
				new QButton ( { … } ),
				…
			]
		*/
		
		var _buttons = l;
		var _qmenu_cssText = "position:fixed; right:0px; top: 30%;";
		var $qmenu = document.createElement ( 'div' );
		$qmenu.id = 'qmenu';
		$qmenu.style.cssText = _qmenu_cssText;
		
		this.buttons = _buttons;
		
		for (i in _buttons)
		{
			if ( _buttons[i] instanceof QButton )
			{
				$qmenu.appendChild(_buttons[i].buttonElement);
			}
		}
		
		this.qmenuElement = $qmenu;
		
	}
	// Qmenu → QButton class
	var QButton = function ( p )
	{
		/*	
			{
				name:		"element-id",
				icon:		"data-url:…",
				hint:		"Text-title attribute"
				onclick:	function (event) {…},
			}
		*/
		
		this.name = p.name ? p.name : '';
		this.icon = p.icon ? p.icon : '';
		this.hint = p.hint ? p.hint : false;
		this.onclick = p.onclick ? p.onclick : function () {};
		
		var $cssText = "width: 32px; height: 32px; background: #000; -webkit-box-shadow: 0px 0px 15px #55F; border-radius: 4px; border-top-right-radius: 0; border-bottom-right-radius: 0; border: 1px solid #333; margin-bottom:12px; cursor: pointer;";
		var $div_button = document.createElement('div');
		$div_button.style.cssText = $cssText;
		$div_button.id = this.name;
		$div_button.class = 'qbutton';
		$div_button.title = this.hint;
		$div_button.addEventListener('click', this.onclick);
		if (this.icon.length > 0)
		{
			var $img_icon = document.createElement('img');
			var _img_icon_cssText = "margin-top: 4px; margin-left: 4px;";
			$img_icon.src = this.icon;
			$img_icon.style.cssText = _img_icon_cssText;
			$div_button.appendChild ($img_icon);
		}
		
		this.buttonElement = $div_button;

	}
	
	//	ScrollCommentsManager class definition
	var ScrollCommentsManager = function ()
	{
		
		var comments = document.getElementsByClassName('new');
		var currentId = 0;
		
		var scrollToId = function ( id )
		{
			if (comments[id].offsetTop)
			{
				window.scroll(0, comments[id].offsetTop);
			}
		}
		
		this.next = function () {
			if (currentId + 1 < comments.length)
			{
				scrollToId(++currentId);
			}
		};
		this.prev = function () {
			if (currentId > 0 )
			{
				scrollToId(--currentId);
			}
		};
	};
	
		// UserComment class definition
		var UserComment = function ( username )
		{
		
			var comment = new String ();
			var tfsp_usercomments = Object.load('tfsp_usercomments');
		
			this.load = function ()
			{
				if (this.username.length > 0 && typeof(this.username)=='string')
				{
					comment = tfsp_usercomments[this.username];
				} else {
					throw 'Unknown username';
				}
				return this;
			}
			this.save = function ()
			{
				if (this.username.length > 0 && typeof(this.username)=='string')
				{
					tfsp_usercomments[this.username] = comment;
					tfsp_usercomments.save('tfsp_usercomments');
				} else {
					throw 'Unknown username';
				}
				return this;
			}
			this.update = function ( comm )
			{
				comment = comm ? comm : comment;
				return this;
			}
			this.username = username ? username : new String ();
			
			this.getComment = function ()
			{
				return comment;
			}
			
		}
		// UserCommentControllerFactory class definition
		var UserCommentControllerFactory = function (username)
		{
			var username = username ? username : false;
			if (!username) throw 'Unknown username';
			var userCommentController = new UserComment (username);
			
			this.produce = function ()
			{
				var $span_comment = document.createElement('span');
				$span_comment.innerText = userCommentController.load().getComment();
				$span_comment.style.cssText = "float: left; font-size: 11pt;   color: rgb(3, 135, 180); min-width: 150px;";
				$span_comment.contentEditable = "true";
				$span_comment.addEventListener('click', function (e){
					console.dir (this);
				});
				$span_comment.addEventListener('blur', function (e){
					if (this.innerText != "")
					{
						userCommentController.update(this.innerText).save();
					} else {
						this.innerText = "Заметки о пользователе. Видны только вам.";
					}
				});
				return $span_comment;
			}
		}
	
	// FavoriteController class definition;
	var FavoriteController = function (type)
	{
		// type: post | comment | episode | user;
		var type = type ? type : false;
		var _prefix = '';
		switch (type)
		{
			case 'post':
				_prefix = 'posts';
			break;
			case 'comment':
				_prefix = 'comments';
			break;
			case 'episode':
				_prefix = 'episodes';
			break;
			case 'user':
				_prefix = 'users';
			break;
			default:
				//throw 'Invalid type. Acceptable values: \"post\", \"comment\", \"episode\", \"user\".';
			break;
		}
		try {
			var favoritesList = Object.load ('tfsp_favorites');
			/*	tfsp_favorites = {
					"posts": ["favPostId_1"]
					"comments": ["favCommentId_1"]
					"episodes": ["favEpisodeHash_1"]
					"users": ["fav_userHash_1"]
				}
			*/
		} catch (e) {
			localStorage['tfsp_favorites'] = '{"posts":[],"comments":[],"episodes":[],"users":[]}';
			var favoritesList = Object.load ('tfsp_favorites');
		}
		var currentTypeList = favoritesList[_prefix];
		
		var isAlready = function (id)
		{
			var id = id;
			return (currentTypeList.filter(function(v){return v==id})).length != 0;
		}
		
		this.add = function (id)
		{
			if (!isAlready(id))
			{
				favoritesList[_prefix].push(id);
				favoritesList.save('tfsp_favorites');
				console.log ('exist now');
				return true;
			}
			return false;
		}
		
		this.remove = function (id)
		{
			if (isAlready(id))
			{
				var newCTL = currentTypeList.filter(function(a){return a!=id});
				currentTypeList = newCTL;
				favoritesList[_prefix] = newCTL;
				favoritesList.save('tfsp_favorites');
				console.log ('not exist now');
				return true;
			}
			return false;
		}
		
		this.toggle = function (id)
		{
			if (isAlready (id))
			{
				console.log ('already exist');
				return this.remove(id);
			} else {
				console.log ('don\'t exest now');
				return this.add(id);
			}
		}
		
		this.isFav = function (id)
		{
			return isAlready(id);
		}
	}
	
	//	StarController class defiition
	var StarController = function ( p )
	{
	
		var hint = p.hint ? p.hint : '';
		var onclick = p.onclick ? p.onclick : function () {};
		var img = p.img ? p.img : '';
		var alt_img = p.img_alter ? p.img_alter : '';
		var isFav = p.isFav ? p.isFav : false;
		var postId = p.postId ? p.postId : 0;
		var _starControllerElement = false;
		
		this.getStarControllerElement = function ()
		{
			if (_starControllerElement == false)	// Default false else HTMLDivElement
			{
				$div_starContainer = document.createElement('div');
				$div_starContainer.style.cssText = "float: left;";
				$a_starAchor = document.createElement('a');
				$a_starAchor.title = hint;
				$a_starAchor.addEventListener('click', onclick);
				$img_starImage = document.createElement('img');
				$img_starImage.src = isFav ? img : alt_img;
				$a_starAchor.appendChild($img_starImage);
				$div_starContainer.appendChild($a_starAchor);
				
				_dataPostId_attribute = document.createAttribute ('data-postId');
				_dataPostId_attribute.nodeValue = postId;
				$a_starAchor.setAttributeNode(_dataPostId_attribute);
				
				_starControllerElement = $div_starContainer;
				
				console.log (isFav);
				
				return $div_starContainer;
			} else {
				return _starControllerElement;
			}
		}
		
		this.getPostId = postId;
	}
	
		
		
	var pd = new PluginDispatcher (
		[
			new Plugin (
				{
					name:	'test_plugin',
					filter:	/\/Watch\/.*/,
					action:	function () {
						var tpc = new this.classes.test_plugin_class ( 'bar, baz' );
						console.log ('test_plugin loaded');
						console.log (tpc.some);
					},
					classes: {
						"test_plugin_class": function ( foo )
						{
							this.some = foo;
						}
					}
				}
			),
			new Plugin (
				{
					name:	'quick_menu',
					filter: /(\/Tlog\/Posts\/.*)|(\/Blog\/Posts\/.*)|(\/Watch\/)/,
					classes: {
						"QMenu": QMenu,
						"QButton": QButton,
						"ScrollCommentsManager": ScrollCommentsManager
					},
					action: function ()
					{
						window.tfsp_scm = new this.classes.ScrollCommentsManager();
						
						var $qmenu = new this.classes.QMenu (
							[
								new this.classes.QButton ( {
									name:		'button-up',
									hint:		'На самый верх',
									icon:		'http://cdn1.iconfinder.com/data/icons/musthave/24/Stock%20Index%20Up.png',
									onclick:	function ( e )
									{
										scroll(0,0);
										console.log (e.target.id+' pressed!');
									}
								}),
								new this.classes.QButton ( {
									name:		'button-next-new',
									hint:		'Следующий новый комментарий',
									icon:		'http://cdn1.iconfinder.com/data/icons/musthave/24/Next.png',
									onclick:	function ( e )
									{
										window.tfsp_scm.next();
									}
								}),
								new this.classes.QButton ( {
									name:		'button-reload',
									hint:		'f5 f5 f5 f5 f5…',
									icon:		'http://cdn1.iconfinder.com/data/icons/musthave/24/Synchronize.png',
									onclick:	function ( e )
									{
										window.location.reload();
									}
								}),
								new this.classes.QButton ( {
									name:		'button-prev-new',
									hint:		'Предыдущий новый комментарий',
									icon:		'http://cdn1.iconfinder.com/data/icons/musthave/24/Previous.png',
									onclick:	function ( e )
									{
										window.tfsp_scm.prev();
									}
								}),
								new this.classes.QButton ( {
									name:		'button-down',
									hint:		'Вниз, только вниз',
									icon:		'http://cdn1.iconfinder.com/data/icons/musthave/24/Stock%20Index%20Down.png',
									onclick:	function ( e )
									{
										scroll(0, document.height);
										console.log (e.target.id+' pressed!');
									}
								})
							]
						);
						document.getElementsByTagName('body')[0].appendChild($qmenu.qmenuElement);
						console.log (this);
					}
				}
			),
			new Plugin (
				{
					name:	"exit_preventer",
					filter:	/\/Watch\/.*/,
					action:	function ()
					{
						console.log ('exit preventer is now loading');
						var $links = document.getElementsByTagName('a');
						for (i=0; i<$links.length; i++)
						{
							$links[i].addEventListener('click', function (e){
								e.preventDefault();
							})
							
							$links[i].addEventListener('dblclick', function (e){
								window.location.href = this.href;
							}, false);
						}
						console.log ('exit preventer is now end work');
					}
				}
			),
			new Plugin (
				{
					name:	"links_hightlighter",
					filter:	/(\/Tlog\/Posts\/.*)|(\/Blog\/Posts\/.*)|(\/Watch\/.*)/,
					action: function ()
					{
						console.log(this);
						var $comments = document.querySelectorAll(".comcontent");
						for (i=0; i < $comments.length; i++)
						{
							$comments[i].innerHTML = $comments[i].innerHTML.replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,"<a href='$1'>$1</a>"); 
						}
					}
				}
			),
			new Plugin (
				{
					name: "show_hidden",
					filter: /(\/Tlog\/Posts\/.*)|(\/Blog\/Posts\/.*)|(\/Watch\/.*)/,
					action: function ()
					{
						console.log(this);
						
						var $button_show = document.createElement('a');
						$button_show.href = "#";
						$button_show.innerText = "Показать все что скрыто!";
						$button_show.style.cssText = "font-size: 8pt;padding-left: 12pt;";
						$button_show.addEventListener ('click', function (e) {
							e.preventDefault();
							
							$silly_billys = document.getElementsByClassName('silly-billy');
							for (i=0; i<$silly_billys.length; i++)
							{
								$silly_billys[i].style.display = "none";
								$silly_billys[i].nextElementSibling.style.display = "block";
							}
							
						});
						
						document.getElementsByClassName("tcom")[0].appendChild($button_show);
						
					}
				}
			),
			new Plugin (
				{
					name:	"user_comment",
					filter:	/\/Users\/.*/,
					classes: {
						"UserCommentControllerFactory": UserCommentControllerFactory
					},
					action: function ()
					{
						var username = window.location.pathname.split('/')[2];
						window.tfsp_UCCF = new this.classes.UserCommentControllerFactory(username);
						$info = document.getElementsByClassName('info')[0];
						$info.appendChild (window.tfsp_UCCF.produce());
					}
				}
			),
			new Plugin (
				{
					name:	"post_favorites",
					filter: /(\/Tlog\/Posts\/.*)|(\/Blog\/Posts\/.*)|(\/Watch\/.*)|(\/Tlog)|(\/Blog)/,
					classes: {
						"StarController": StarController,
						"FavoriteController": FavoriteController
					},
					action: function () {
						console.log (this);
						window.tfsp_posts_favoriteController = new this.classes.FavoriteController('post');
						// window.tfsp_comments_favoriteController = new this.classes.FavoriteController('comment');
						// window.tfsp_episodes_favoriteController = new this.classes.FavoriteController('episode');
						// window.tfsp_users_favoriteController = new this.classes.FavoriteController('user');
						if (/\/Tlog[\/]?/.test(window.location.pathname))
						{
							var $post_places = document.querySelectorAll('[id^="post"] .blogpostauthorline');
							for (i=0; i<$post_places.length; i++)
							{
								var postId = $post_places[i].parentElement.parentElement.parentElement.id.slice(4);
								var img_normal = 'http://cdn1.iconfinder.com/data/icons/uidesignicons/star_empty.png'
								var img_alter = 'http://cdn1.iconfinder.com/data/icons/uidesignicons/star_full.png';
								var $i_starController = new this.classes.StarController(
									{
										hint: 'В избранное!',
										img: img_normal,
										img_alter: img_alter,
										isFav: window.tfsp_posts_favoriteController.isFav(postId),
										postId: postId,
										onclick: function (e)
										{
											window.tfsp_posts_favoriteController.toggle(this.attributes['data-postId'].value);
											console.log (this.firstElementChild);
											if (this.firstElementChild.src == img_normal){
												this.firstElementChild.src = img_alter;
											} else {
												this.firstElementChild.src = img_normal;
											}
										}
									}
								);
								$post_places[i].appendChild($i_starController.getStarControllerElement());
							}
						}
					}
				}
			)
		]
	);
	
})( window );